#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "hostdetail.h"
#include "NetworkSanner.h"
#include "ThreadPool.h"
#include <QTreeWidget>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QString title = QString("%1 V%2 (64-bit, windows)").arg(QCoreApplication::applicationName()).arg(QCoreApplication::applicationVersion());
    setWindowTitle(title);

    // 注册信号槽参数
    qRegisterMetaType<QVector<int>>("QVector<int>");

    ThreadPool::instance();

    hostdetail::showSelfHostDetail(ui->tableWidget_selfhost);
    ui->progressBar->hide();// 隐藏进度条

    m_scanner = new NetworkSanner(this);
    connect(m_scanner, &NetworkSanner::SendARPItem, [&](QString dstIp, QString dstMac){
        QTreeWidgetItem* newTopItem = new QTreeWidgetItem(QStringList{dstIp, dstMac});
        ui->arp_treeWidget->addTopLevelItem(newTopItem);
    });

    connect(m_scanner, &NetworkSanner::SendICMPInfo, [&](QString dstIp, bool bIsAlive){
        ui->icmp_scan_Btn->setDisabled(false);
        ui->icmp_treeWidget->addTopLevelItem(new QTreeWidgetItem({dstIp, bIsAlive ? "✔" : "✘"}));
    });

    // ARP
    ui->arp_progressBar->hide();
    ui->arp_scan_cancel_btn->setDisabled(true);
    ui->arp_scan_btn->setDisabled(false);
    ui->arp_startIp_lineEdit->setText("10.4.16.70");
    ui->arp_endIp_lineEdit->setText("10.4.16.113");

    // ICMP
    ui->icmp_dstIp_lineEdit->setText("10.4.16.113");

    // TCP Connect
    ui->tcp_connect_dstIp_lineEdit->setText("127.0.0.1");
    ui->tcp_connect_startIp_lineEdit->setText("10.4.16.1");
    ui->tcp_connect_endIp_lineEdit->setText("10.4.16.255");
    connect(m_scanner, &NetworkSanner::SendTCPConnectItem, [&](QVector<QString> item){
        QTreeWidgetItem* child = new QTreeWidgetItem(ui->tcp_connect_treeWidget);
        child->setText(0, item[0]);
        child->setText(1, item[1]);
        child->setText(2, item[2]);
        child->setText(3, item[3]);
    });
    connect(m_scanner, &NetworkSanner::TCPConnectEnd, [&](){
        ui->tcp_connect_scan_Btn->setDisabled(false);
        ui->tcp_connect_scan_cancel_Btn->setDisabled(true);
    });

    // TCP Syn
    ui->tcp_syn_dstIp_lineEdit->setText("www.bilibili.com");
    ui->tcp_syn_scan_cancel_Btn->setDisabled(true);
    connect(m_scanner, &NetworkSanner::SendTCPSynItem, [&](QVector<QString> item){
        QTreeWidgetItem* child = new QTreeWidgetItem(ui->tcp_syn_treeWidget);
        child->setText(0, item[0]);
        child->setText(1, item[1]);
        child->setText(2, item[2]);
        child->setText(3, item[3]);
    });

    connect(&m_timer, &QTimer::timeout, [this](){
        if(m_timer.isActive())
        {
            m_timer.stop();
        }
        ui->tcp_syn_scan_Btn->setDisabled(false);
        ui->tcp_syn_scan_cancel_Btn->setDisabled(true);
        if(m_scanner)
        {
            m_scanner->StopTCPSyn();
        }
    });

    // TCP Fin
    ui->tcp_fin_dstIp_lineEdit->setText("www.bilibili.com");
    ui->tcp_fin_scan_cancel_Btn->setDisabled(true);
    connect(m_scanner, &NetworkSanner::SendTCPFinItem, [&](QVector<QString> item){
        QTreeWidgetItem* child = new QTreeWidgetItem(ui->tcp_fin_treeWidget);
        child->setText(0, item[0]);
        child->setText(1, item[1]);
        child->setText(2, item[2]);
        child->setText(3, item[3]);
    });

    connect(&m_tcp_fin_timer, &QTimer::timeout, [this](){
        if(m_tcp_fin_timer.isActive())
        {
            m_tcp_fin_timer.stop();
        }
        ui->tcp_fin_scan_Btn->setDisabled(false);
        ui->tcp_fin_scan_cancel_Btn->setDisabled(true);
        if(m_scanner)
        {
            m_scanner->StopTCPFin();
        }
    });

    // UDP
    ui->udp_dstIp_lineEdit->setText("www.bilibili.com");
    ui->udp_scan_cancel_Btn->setDisabled(true);
    connect(m_scanner, &NetworkSanner::SendUDPItem, [&](QVector<QString> item){
        QTreeWidgetItem* child = new QTreeWidgetItem(ui->udp_treeWidget);
        child->setText(0, item[0]);
        child->setText(1, item[1]);
        child->setText(2, item[2]);
        child->setText(3, item[3]);
    });
    connect(&m_udp_timer, &QTimer::timeout, [this]{
        if(m_udp_timer.isActive())
        {
            m_udp_timer.stop();
        }
        ui->udp_scan_Btn->setDisabled(false);
        ui->udp_scan_cancel_Btn->setDisabled(true);
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_arp_scan_btn_clicked()
{
    ui->arp_scan_cancel_btn->setDisabled(false);
    ui->arp_scan_btn->setDisabled(true);
    // ui->arp_progressBar->show();

    QString startIPStr = ui->arp_startIp_lineEdit->text();
    QString endIPStr = ui->arp_endIp_lineEdit->text();

    if(m_scanner->CheckIP(startIPStr) && m_scanner->CheckIP(endIPStr))
    {
        ThreadPool::instance().commit([=](){
            m_scanner->Arp_Scan(startIPStr, endIPStr);
        });
    }
}

void MainWindow::on_icmp_scan_Btn_clicked()
{
    ui->icmp_scan_Btn->setDisabled(true);

    QString dstIPStr = ui->icmp_dstIp_lineEdit->text();

    if(m_scanner->CheckIP(dstIPStr))
    {
        ThreadPool::instance().commit([=](){
            m_scanner->ICMP_Scan(dstIPStr);
        });
    }
}

void MainWindow::on_tcp_connect_scan_Btn_clicked()
{
    ui->tcp_connect_scan_Btn->setDisabled(true);
    ui->tcp_connect_scan_cancel_Btn->setDisabled(false);

    QString startIPStr = ui->tcp_connect_startIp_lineEdit->text();
    QString endIPStr = ui->tcp_connect_endIp_lineEdit->text();
    QString dstIPStr = ui->tcp_connect_dstIp_lineEdit->text();
    ushort startPort = ui->tcp_connect_startport_spinBox->value();
    ushort endPort = ui->tcp_connect_endport_spinBox->value();
    ushort dstPort = ui->tcp_connect_port_spinBox->value();

    if(startPort > endPort || !m_scanner || !m_scanner->CheckIP(startIPStr) || !m_scanner->CheckIP(endIPStr)) return;

    ui->tcp_connect_treeWidget->clear();
    if(ui->tcp_connect_comboBox->currentIndex() == 0)
    {
        ThreadPool::instance().commit([=](){
            m_scanner->TCP_Connect_Scan(dstIPStr, dstIPStr, startPort, endPort);
        });
    }
    else
    {
        ThreadPool::instance().commit([=](){
            m_scanner->TCP_Connect_Scan(startIPStr, endIPStr, dstPort, dstPort);
        });
    }
}

void MainWindow::on_tcp_syn_scan_Btn_clicked()
{
    m_timer.start(6000);
    ui->tcp_syn_scan_Btn->setDisabled(true);
    ui->tcp_syn_scan_cancel_Btn->setDisabled(false);

    QString dstIPStr = ui->tcp_syn_dstIp_lineEdit->text();
    ushort startPort = ui->tcp_syn_startport_spinBox->value();
    ushort endPort = ui->tcp_syn_endport_spinBox->value();

    if(startPort > endPort || !m_scanner) return;

    ui->tcp_syn_treeWidget->clear();
    ThreadPool::instance().commit([=](){
        m_scanner->StartTCPSyn();
        m_scanner->TCP_Syn_Scan(dstIPStr, startPort, endPort);
    });
}

void MainWindow::on_tcp_fin_scan_Btn_clicked()
{
    m_tcp_fin_timer.start(3000);
    ui->tcp_fin_scan_Btn->setDisabled(true);
    ui->tcp_fin_scan_cancel_Btn->setDisabled(false);

    QString dstIPStr = ui->tcp_fin_dstIp_lineEdit->text();
    ushort startPort = ui->tcp_fin_startport_spinBox->value();
    ushort endPort = ui->tcp_fin_endport_spinBox->value();

    if(startPort > endPort || !m_scanner) return;

    ui->tcp_fin_treeWidget->clear();
    ThreadPool::instance().commit([=](){
        m_scanner->StartTCPFin();
        m_scanner->TCP_Fin_Scan(dstIPStr, startPort, endPort);
    });
}

void MainWindow::on_udp_scan_Btn_clicked()
{
    m_udp_timer.start(5000);
    ui->udp_scan_Btn->setDisabled(true);
    ui->udp_scan_cancel_Btn->setDisabled(false);

    QString dstIPStr = ui->udp_dstIp_lineEdit->text();
    ushort startPort = ui->udp_startport_spinBox->value();
    ushort endPort = ui->udp_endport_spinBox->value();

    if(startPort > endPort || !m_scanner) return;

    ui->udp_treeWidget->clear();
    ThreadPool::instance().commit([=](){
        m_scanner->UDP_Scan(dstIPStr, startPort, endPort);
    });
}

